/***************************************************************************
 *   Copyright (C) 2010 by Mark Pictor                                     *
 *   mpictor@gmail.com                                                     *
 *   modifications Copyright (C) 2011 by Anders Wallin                     *
 *   anders.e.e.wallin@gmail.com                                           *      
 *   modified by Kazuyasu Hamada 2015, k-hamada@gifu-u.ac.jp               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef GTOM_HH
#define GTOM_HH

#include <vector>
#include <limits.h>
#include <iostream>
#include <fstream>

#include <QString>
#include <QProcess>
#include <QObject>

#include "canonLine.hpp"

namespace g2m {

/// \brief This class runs the interpreter ("rs274"), and creates a canonLine object for each canonical 
///  command generated by the interpreter. 
class g2m : public QObject {
    Q_OBJECT;

    public:
        g2m()  { debug = false; initialPos = Pose( Point(0,0,0), Point(0,0,0) ); userOrigin  = Pose( Point(0,0,0), Point(0,0,0) ); total_gcode_lines = 0; }
        /// return vector of canonLines
        std::vector<canonLine*> getCanonLines() { return lineVector; }
        void setInitialPos(Pose init) { initialPos = init; }
        void setOrigin(Pose origin) { userOrigin = origin; }
        Pose getOrigin() { return userOrigin; }
        int toGcodeLineNo(int canonLineNo) {
        	if ((unsigned)canonLineNo + 1 >= lineTable.size())
        		return ++canonLineNo;
        	else
        		return lineTable[canonLineNo];
        }

    public slots:
        /// run the interpreter
        void interpret_file();
        /// set the path to the .ngc g-code file
        void setFile(QString infile) {
            emit debugMessage( tr("g2m: setting file %1").arg(infile) ); 
            file = infile; 
        }
        /// set the path to the tootable
        void setToolTable(QString tbl_file) { 
            emit debugMessage( tr("g2m: setting tooltable %1").arg(tbl_file) ); 
            tooltable = tbl_file; 
        }
        /// set the path to the rs274 binary
        void setInterp(QString interp_binary) { 
            emit debugMessage( tr("g2m: setting rs274 path:  %1").arg(interp_binary) ); 
            interp = interp_binary; 
        }
        
        /// set debug mode on/off
        void setDebug(bool d) {debug = d;}
        
    signals:
        /// debug messages
        void debugMessage(QString s);
        /// emitted while .ngc g-code file is read. the g-code line read.
        void gcodeLineMessage(QString s);
        /// emitted during interpret(), the canon line as a string
        void canonLineMessage(QString s);
        /// emitted during interpret(), the current canonLine object
        void signalCanonLine(canonLine* line);
        
    protected:    
        bool chooseToolTable();
        bool startInterp(QProcess &tc);
        void interpret();
        bool processCanonLine(std::string l);
        void infoMsg(std::string s);
bool startInterp2(QProcess &tc, QString tempFile);
void interpret2(QString tempFile);
        /// the canonLines produced when interpreting g-code
        std::vector<canonLine*> lineVector;
        /// path to .ngc g-code file
        QString file;
        /// path to tooltable
        QString tooltable;
        /// path to rs274 executable
        QString interp;
        /// flag for debug mode
        bool debug;
        /// number of lines in the .ngc g-code file
        int gcode_lines;

    private:
        Pose initialPos;
        Pose userOrigin;

        int total_gcode_lines;
        std::vector<int> lineTable;
};

} // end namespace
#endif //GTOM_HH
